package mx.ipn.persistencia.mysql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import mx.ipn.persistencia.FabricaDeDAOs;
import mx.ipn.persistencia.dao.BaseDAO;
import mx.ipn.persistencia.dao.TipoBaseDAO;
import mx.ipn.persistencia.dao.DireccionDAO;
import mx.ipn.to.BaseTO;
import mx.ipn.to.TipoBaseTO;
import mx.ipn.to.DireccionTO;

//BaseDAOMySQL es la implementación de la interfaz BaseDAO.
//Esta clase contiene todo el codigo especifico de MySQL
//Así como los querys SQL.
//El cliente se salva de conocer los detalles de implementación.

public class BaseDAOMySQL implements BaseDAO {
	static{FabricaDeDAOsMySQL.iniciaLog(BaseDAOMySQL.class);}

	private static final String INSERT = "INSERT INTO base (numero_cajones,id_direccion,id_tipo_base) VALUES(?,?,?)";
	private static final String DELETE = "DELETE FROM base WHERE id_base=?";
	private static final String UPDATE = "UPDATE base SET numero_cajones=?,id_direccion=?,id_tipo_base=? WHERE id_base=?";
	private static final String FINDBYID = "SELECT * FROM base WHERE id_base=?";
	private static final String SELECT = "SELECT * FROM base";
	private static final String SELECTBYTIPOBASE = "SELECT * FROM base WHERE id_tipo_base=?";

	@Override
	public short deleteBase(int idBase) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(DELETE);

			ps.setInt(1, idBase);

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			}

			else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

	@Override
	public BaseTO findBaseById(int idBase) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYID);

			ps.setInt(1, idBase);

			ResultSet rs = ps.executeQuery();
			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			DireccionDAO direccionDAO = fabricaMySQL.getDireccionDAO();
			TipoBaseDAO tipoBaseDAO = fabricaMySQL.getTipoBaseDAO();
			if (rs.next()) {
				idBase = rs.getInt("id_base");
				short numeroCajones = rs.getShort("numero_cajones");
				int idDireccion = rs.getInt("id_direccion");
				short idTipoBase = rs.getShort("id_tipo_base");

				DireccionTO direccionTO = direccionDAO
						.findDireccionById(idDireccion);
				TipoBaseTO tipoBaseTO = tipoBaseDAO
						.findTipoBaseById(idTipoBase);

				ArrayList<DireccionTO> listDireccionTO = new ArrayList<DireccionTO>();

				listDireccionTO.add(direccionTO);

				DireccionTO[] arrDireccionTO = (DireccionTO[]) listDireccionTO.toArray(new DireccionTO[listDireccionTO.size()]);
				
				BaseTO baseTO = new BaseTO(idBase, numeroCajones,
						arrDireccionTO, tipoBaseTO);

				ps.close();
				conexion.close();
				return baseTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public boolean insertBase(BaseTO baseTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(INSERT);

			ps.setShort(1, baseTO.getNumeroCajones());
			ps.setInt(2, baseTO.getIdDireccion());
			ps.setShort(3, baseTO.getTipoBaseTo().getIdTipoBase());
			ps.executeUpdate();

			ps.close();
			conexion.close();

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public ArrayList<BaseTO> selectBase() {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(SELECT);

			ResultSet rs = ps.executeQuery();
			FabricaDeDAOs fabricaMySQL = FabricaDeDAOs
					.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);
			DireccionDAO direccionDAO = fabricaMySQL.getDireccionDAO();
			TipoBaseDAO tipoBaseDAO = fabricaMySQL.getTipoBaseDAO();

			ArrayList<BaseTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<BaseTO>();
				int idBase = rs.getInt("id_base");
				short numeroCajones = rs.getShort("numero_cajones");
				int idDireccion = rs.getInt("id_direccion");
				short idTipoBase = rs.getShort("id_tipo_base");

				DireccionTO direccionTO = direccionDAO
						.findDireccionById(idDireccion);
				TipoBaseTO tipoBaseTO = tipoBaseDAO
						.findTipoBaseById(idTipoBase);

				ArrayList<DireccionTO> listDireccionTO = new ArrayList<DireccionTO>();
				listDireccionTO.add(direccionTO);

				DireccionTO[] arrDireccionTO = (DireccionTO[]) listDireccionTO.toArray(new DireccionTO[listDireccionTO.size()]);
			
				BaseTO baseTO = new BaseTO(idBase, numeroCajones,
						arrDireccionTO, tipoBaseTO);
				coleccion.add(baseTO);
			}

			ps.close();
			conexion.close();

			
			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public BaseTO selectBaseByTipoBase(short idTipoBase) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();
			
			FabricaDeDAOs fabricaMySQL = null;
			
			DireccionDAO direccionDAO = null;
			TipoBaseDAO tipoBaseDAO = null;

			ArrayList<Integer> listIdBase = null;
			ArrayList<Short> listNumeroCajones = null;
			ArrayList<DireccionTO> listDireccionTO = null;

			BaseTO baseTO = null;

			PreparedStatement ps = conexion.prepareStatement(SELECTBYTIPOBASE);
			ps.setShort(1, idTipoBase);
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				if (listIdBase == null) {

					listIdBase = new ArrayList<Integer>();
					listNumeroCajones = new ArrayList<Short>();
					listDireccionTO = new ArrayList<DireccionTO>();

					fabricaMySQL = FabricaDeDAOs
							.getFabricaDeDAOs(mx.ipn.Constantes.FABRICA_DAOS_MYSQL);

					direccionDAO = fabricaMySQL.getDireccionDAO();
					tipoBaseDAO = fabricaMySQL.getTipoBaseDAO();
				}

				listIdBase.add(rs.getInt("id_base"));
				listNumeroCajones.add(rs.getShort("numero_cajones"));
				listDireccionTO.add(direccionDAO.findDireccionById(rs
						.getInt("id_direccion")));

			}
			if (listIdBase != null) {
				Integer[] arrIdBase = (Integer[]) listIdBase.toArray(new Integer[listIdBase.size()]);
				Short[] arrNumeroCajones = (Short[]) listNumeroCajones.toArray(new Short[listNumeroCajones.size()]);
				DireccionTO[] arrDireccionTO = (DireccionTO[]) listDireccionTO.toArray(new DireccionTO[listDireccionTO.size()]);
				
				baseTO = new BaseTO(arrIdBase, arrNumeroCajones,
						arrDireccionTO, tipoBaseDAO
								.findTipoBaseById(idTipoBase));
			}
			ps.close();
			conexion.close();
			return baseTO;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public short updateBase(BaseTO baseTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(UPDATE);

			ps.setShort(1, baseTO.getNumeroCajones());
			ps.setInt(2, baseTO.getIdDireccion());
			ps.setShort(3, baseTO.getTipoBaseTo().getIdTipoBase());
			ps.setInt(4, baseTO.getIdBase());
			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			}

			else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

}
